Čeština

Ovládněte React Error Boundaries pro vytváření odolných a uživatelsky přívětivých aplikací. Naučte se osvědčené postupy, techniky implementace a pokročilé strategie zpracování chyb.

React Error Boundaries: Techniky elegantního zpracování chyb pro robustní aplikace

V dynamickém světě webového vývoje je vytváření robustních a uživatelsky přívětivých aplikací nanejvýš důležité. React, populární JavaScriptová knihovna pro vytváření uživatelských rozhraní, poskytuje výkonný mechanismus pro elegantní zpracování chyb: Error Boundaries. Tato komplexní příručka se ponoří do konceptu Error Boundaries, zkoumá jejich účel, implementaci a osvědčené postupy pro vytváření odolných React aplikací.

Pochopení potřeby Error Boundaries

React komponenty, stejně jako jakýkoli kód, jsou náchylné k chybám. Tyto chyby mohou pramenit z různých zdrojů, včetně:

Bez řádného zpracování chyb může chyba v React komponentě zhroutit celou aplikaci, což má za následek špatnou uživatelskou zkušenost. Error Boundaries poskytují způsob, jak tyto chyby zachytit a zabránit jim v šíření po stromu komponent, a zajistit tak, že aplikace zůstane funkční i v případě selhání jednotlivých komponent.

Co jsou React Error Boundaries?

Error Boundaries jsou React komponenty, které zachycují JavaScriptové chyby kdekoli ve stromu podřízených komponent, zaznamenávají tyto chyby a zobrazují náhradní uživatelské rozhraní namísto stromu komponent, který se zhroutil. Fungují jako bezpečnostní síť, která zabraňuje zhroucení celé aplikace v důsledku chyb.

Klíčové charakteristiky Error Boundaries:

Implementace Error Boundaries

Pojďme si projít proces vytváření základní Error Boundary komponenty:

1. Vytvoření Error Boundary komponenty

Nejprve vytvořte novou třídní komponentu, například s názvem ErrorBoundary:


import React from 'react';

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      hasError: false
    };
  }

  static getDerivedStateFromError(error) {
    // Aktualizuje stav, takže další vykreslení zobrazí náhradní UI.
    return {
      hasError: true
    };
  }

  componentDidCatch(error, errorInfo) {
    // Můžete také zalogovat chybu do služby pro hlášení chyb
    console.error("Chycená chyba: ", error, errorInfo);
    // Příklad: logErrorToMyService(error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      // Můžete vykreslit libovolné vlastní náhradní UI
      return (
        <div>
          <h2>Něco se pokazilo.</h2>
          <details style={{ whiteSpace: 'pre-wrap' }}>
            {this.state.error && this.state.error.toString()}
            <br />
            {this.state.errorInfo.componentStack}
          </details>
        </div>
      );
    }

    return this.props.children; 
  }
}

export default ErrorBoundary;

Vysvětlení:

2. Použití Error Boundary

Chcete-li použít Error Boundary, jednoduše zabalte jakoukoli komponentu, která by mohla vyvolat chybu, do komponenty ErrorBoundary:


import ErrorBoundary from './ErrorBoundary';

function MyComponent() {
  // Tato komponenta může vyvolat chybu
  return (
    <ErrorBoundary>
      <PotentiallyBreakingComponent />
    </ErrorBoundary>
  );
}

export default MyComponent;

Pokud PotentiallyBreakingComponent vyvolá chybu, ErrorBoundary ji zachytí, zaloguje chybu a vykreslí náhradní uživatelské rozhraní.

3. Ilustrativní příklady s globálním kontextem

Představte si aplikaci pro elektronické obchodování, která zobrazuje informace o produktech načtené ze vzdáleného serveru. Komponenta ProductDisplay je zodpovědná za vykreslování podrobností o produktu. Server však může občas vrátit neočekávaná data, což vede k chybám vykreslování.


// ProductDisplay.js
import React from 'react';

function ProductDisplay({ product }) {
  // Simulace potenciální chyby, pokud product.price není číslo
  if (typeof product.price !== 'number') {
    throw new Error('Neplatná cena produktu');
  }

  return (
    <div>
      <h2>{product.name}</h2>
      <p>Cena: {product.price}</p>
      <img src={product.imageUrl} alt={product.name} />
    </div>
  );
}

export default ProductDisplay;

Chcete-li se chránit před takovými chybami, zabalte komponentu ProductDisplay do komponenty ErrorBoundary:


// App.js
import React from 'react';
import ErrorBoundary from './ErrorBoundary';
import ProductDisplay from './ProductDisplay';

function App() {
  const product = {
    name: 'Example Product',
    price: 'Not a Number', // Záměrně nesprávná data
    imageUrl: 'https://example.com/image.jpg'
  };

  return (
    <div>
      <ErrorBoundary>
        <ProductDisplay product={product} />
      </ErrorBoundary>
    </div>
  );
}

export default App;

V tomto scénáři, protože product.price je záměrně nastaveno na řetězec místo čísla, komponenta ProductDisplay vyvolá chybu. Komponenta ErrorBoundary tuto chybu zachytí, zabrání zhroucení celé aplikace a zobrazí náhradní uživatelské rozhraní namísto poškozené komponenty ProductDisplay.

4. Error Boundaries v internacionalizovaných aplikacích

Při vytváření aplikací pro globální publikum by měly být chybové zprávy lokalizovány, aby poskytovaly lepší uživatelskou zkušenost. Error Boundaries lze použít ve spojení s knihovnami pro internacionalizaci (i18n) k zobrazení přeložených chybových zpráv.


// ErrorBoundary.js (s podporou i18n)
import React from 'react';
import { useTranslation } from 'react-i18next'; // Za předpokladu, že používáte react-i18next

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      hasError: false,
      error: null,
      errorInfo: null,
    };
  }

  static getDerivedStateFromError(error) {
    return {
      hasError: true,
      error: error,
    };
  }

  componentDidCatch(error, errorInfo) {
    console.error("Chycená chyba: ", error, errorInfo);
    this.setState({errorInfo: errorInfo});
  }

  render() {
    if (this.state.hasError) {
      return (
        <FallbackUI error={this.state.error} errorInfo={this.state.errorInfo}/>
      );
    }

    return this.props.children;
  }
}

const FallbackUI = ({error, errorInfo}) => {
  const { t } = useTranslation();

  return (
    <div>
      <h2>{t('error.title')}</h2>
      <p>{t('error.message')}</p>
      <details style={{ whiteSpace: 'pre-wrap' }}>
        {error && error.toString()}<br />
        {errorInfo?.componentStack}
      </details>
    </div>
  );
}


export default ErrorBoundary;

V tomto příkladu používáme react-i18next k překladu názvu a zprávy chyby v náhradním uživatelském rozhraní. Funkce t('error.title') a t('error.message') načtou příslušné překlady na základě jazyka vybraného uživatelem.

5. Aspekty pro vykreslování na straně serveru (SSR)

Při používání Error Boundaries v aplikacích vykreslovaných na straně serveru je důležité správně zpracovávat chyby, aby se zabránilo zhroucení serveru. Dokumentace React doporučuje, abyste se vyhnuli používání Error Boundaries k obnovení z chyb vykreslování na serveru. Místo toho zpracovávejte chyby před vykreslením komponenty nebo vykreslete statickou chybovou stránku na serveru.

Osvědčené postupy pro používání Error Boundaries

Pokročilé strategie zpracování chyb

1. Mechanismy opakování

V některých případech může být možné se z chyby zotavit opakováním operace, která ji způsobila. Pokud například selže síťový požadavek, můžete jej po krátké prodlevě zopakovat. Error Boundaries lze kombinovat s mechanismy opakování, aby poskytovaly odolnější uživatelskou zkušenost.


// ErrorBoundaryWithRetry.js
import React from 'react';

class ErrorBoundaryWithRetry extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      hasError: false,
      retryCount: 0,
    };
  }

  static getDerivedStateFromError(error) {
    return {
      hasError: true,
    };
  }

  componentDidCatch(error, errorInfo) {
    console.error("Chycená chyba: ", error, errorInfo);
  }

  handleRetry = () => {
    this.setState(prevState => ({
      hasError: false,
      retryCount: prevState.retryCount + 1,
    }), () => {
      // To vynutí opětovné vykreslení komponenty. Zvažte lepší vzory s řízenými props.
      this.forceUpdate(); // VAROVÁNÍ: Používejte s opatrností
      if (this.props.onRetry) {
          this.props.onRetry();
      }
    });
  };

  render() {
    if (this.state.hasError) {
      return (
        <div>
          <h2>Něco se pokazilo.</h2>
          <button onClick={this.handleRetry}>Zkusit znovu</button>
        </div>
      );
    }

    return this.props.children;
  }
}

export default ErrorBoundaryWithRetry;

Komponenta ErrorBoundaryWithRetry obsahuje tlačítko pro opakování, které po kliknutí resetuje stav hasError a znovu vykreslí podřízené komponenty. Můžete také přidat retryCount pro omezení počtu opakování. Tento přístup může být obzvláště užitečný pro zpracování přechodných chyb, jako jsou dočasné výpadky sítě. Ujistěte se, že je prop `onRetry` zpracován odpovídajícím způsobem a znovu načítá/vykonává logiku, která mohla způsobit chybu.

2. Příznaky funkcí

Příznaky funkcí vám umožňují dynamicky povolit nebo zakázat funkce ve vaší aplikaci bez nasazení nového kódu. Error Boundaries lze použít ve spojení s příznaky funkcí k elegantní degradaci funkčnosti v případě chyby. Pokud například konkrétní funkce způsobuje chyby, můžete ji zakázat pomocí příznaku funkce a zobrazit uživateli zprávu, že funkce je dočasně nedostupná.

3. Vzor jističe

Vzor jističe je vzor návrhu softwaru používaný k zabránění aplikaci v opakovaných pokusech o provedení operace, která pravděpodobně selže. Funguje tak, že monitoruje míru úspěšnosti a selhání operace, a pokud míra selhání překročí určitou prahovou hodnotu, „otevře obvod“ a zabrání dalším pokusům o provedení operace na určitou dobu. To může pomoci zabránit kaskádovým selháním a zlepšit celkovou stabilitu aplikace.

Error Boundaries lze použít k implementaci vzoru jističe v aplikacích React. Když Error Boundary zachytí chybu, může zvýšit čítač selhání. Pokud čítač selhání překročí prahovou hodnotu, může Error Boundary zobrazit uživateli zprávu, že funkce je dočasně nedostupná, a zabránit dalším pokusům o provedení operace. Po určité době může Error Boundary „uzavřít obvod“ a znovu povolit pokusy o provedení operace.

Závěr

React Error Boundaries jsou nezbytným nástrojem pro vytváření robustních a uživatelsky přívětivých aplikací. Implementací Error Boundaries můžete zabránit zhroucení celé aplikace v důsledku chyb, poskytnout uživatelům elegantní náhradní uživatelské rozhraní a logovat chyby do monitorovacích služeb pro ladění a analýzu. Dodržováním osvědčených postupů a pokročilých strategií uvedených v této příručce můžete vytvářet React aplikace, které jsou odolné, spolehlivé a poskytují pozitivní uživatelskou zkušenost, a to i tváří v tvář neočekávaným chybám. Nezapomeňte se zaměřit na poskytování užitečných chybových zpráv, které jsou lokalizovány pro globální publikum.